#ifndef __CLIENT_COMMON_TABLE_CACHED_included
#define __CLIENT_COMMON_TABLE_CACHED_included

#include "Table.h"
#include "DBHelper.h"
#include "../engine/DebugStream.h"

namespace Client {
namespace Common {

template<class T>
class CTableCached : public CTable {

	boost::shared_ptr<CDBCursor> mCursor;

public:

	CTableCached(boost::shared_ptr<CDBCursor> c) :
		CTable(c->GetCount()),
		mCursor(c)
	{ }

	virtual ~CTableCached() { }

	virtual void Close() {
		mCursor.reset();
	}

	virtual void Add(RecordRef r) { throw new std::exception("don't call CTableCached::Add()"); }
	virtual string& ToString() { throw new std::exception("don't call CTableCached::ToString()"); }

	virtual boost::shared_array<RecordRef>& NextRecords(int n) {
		
		int first, last;
		CalcNextRecordsIndex(n, first, last);
		if(first == 0 && GetPos() != 0) mCursor->Reset();

		n = last - first + 1;
		boost::shared_array<RecordRef> arr(new RecordRef[n]);
		int i;
		for(i = 0; i < n; i++) {
			if(!mCursor->Step()) break;
			arr[i] = RecordRef(new T(*mCursor));
		}

		if(i == 0) {
			mCurrentRecords.reset();
		}
		else
		if(i == n) {
			mCurrentRecords = arr;
		}
		else {
			n = i;
			mCurrentRecords = boost::shared_array<RecordRef>(new RecordRef[n]);
			for(i = 0; i < n; i++) mCurrentRecords[i] = arr[i];
		}

		CommitRecordsIndex(first, first+n-1);

		return mCurrentRecords;
	}

	static TableRef Query(string& table, string& cond, string& order) {

		DBCursorRef c = CDBHelper::GetInstance().Query(table, cond, order);
		if(c && c->GetCount() > 0) {
			return TableRef(new CTableCached<T>(c));
		}

		return TableRef();
	}
};

} // Common
} // Client

#endif //__CLIENT_COMMON_TABLE_CACHED_included